package driver.android;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.text.InputType;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import androidx.core.content.res.ResourcesCompat;

import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;

import driver.android.http.CommonOkHttpClient;
import driver.util.Constants;
import driver.util.IHttpCallBack;
import driver.util.Util;
import okhttp3.Response;

public class FlashDriverLoginActivity extends Activity implements View.OnClickListener, IHttpCallBack, CompoundButton.OnCheckedChangeListener {

    private EditText mUserNameEditText;
    private EditText mUserPwdEditText;
    private Button mLoginButton;
    private ImageView mCleanUserNameImageView;
    private ImageView mCleanUserPwdImageView;
    private ImageView mShowUserPwdImageView;
    private SharedPreferences mFlashSharedPreferences;
    private String mFlashSharePreferenceName = "Flash";
    private ProgressDialog mProgressDialog;
    private FlashDriverHandler mHandler;
    private boolean mSaveUserInfo;
    private CheckBox mSaveUserInfoCheckBox;
    private boolean loginStatus = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.f_login_activity_main);
        initView();
        updateUserInfo();
    }

    @Override
    protected void onResume() {
        super.onResume();
        Util.debugApp('d', "login activity onResume");
    }

    private void initView() {
        mUserNameEditText = (EditText) this.findViewById(R.id.login_user_name_edit);
        mUserPwdEditText = (EditText) this.findViewById(R.id.login_user_pwd_edit);
        mLoginButton = (Button) this.findViewById(R.id.login_button);
        mCleanUserNameImageView = (ImageView) this.findViewById(R.id.user_name_clear);
        mCleanUserPwdImageView = (ImageView) this.findViewById(R.id.user_pwd_clear);
        mShowUserPwdImageView = (ImageView) this.findViewById(R.id.user_pwd_show);
        mHandler = new FlashDriverHandler(this);
        mSaveUserInfoCheckBox = (CheckBox) this.findViewById(R.id.save_checkbox);
        mSaveUserInfoCheckBox.setOnCheckedChangeListener(this);
        mProgressDialog = new ProgressDialog(this);
        mLoginButton.setOnClickListener(this);
        mCleanUserNameImageView.setOnClickListener(this);
        mCleanUserPwdImageView.setOnClickListener(this);
        mShowUserPwdImageView.setOnClickListener(this);
        mShowUserPwdImageView.setTag(R.id.password_show, false);
        mFlashSharedPreferences = getSharedPreferences(mFlashSharePreferenceName, Context.MODE_PRIVATE);
    }

    //  check user info and update the view
    private void updateUserInfo() {
        loginStatus = true;
        String userName = mFlashSharedPreferences.getString("userName", "");
        Util.debugApp('d', "login activity onResume get user name from Share Preferences" + userName);
        if (userName.length() > 0) {
            mUserNameEditText.setText(userName);
            mSaveUserInfoCheckBox.setChecked(true);
        } else {
            mUserNameEditText.setText("");
            mSaveUserInfoCheckBox.setChecked(false);
        }
        String token = mFlashSharedPreferences.getString("token", "");
        Util.debugApp('d', "login activity onResume get token from Share Preferences " + token);
        if (Util.DEBUG) {
            mUserNameEditText.setText("yupenglyu@gmail.com");
            mUserPwdEditText.setText("fs001");
        }
        if (token.length() > 0) {
            loginStatus = false;
            showTaskListActivity();
        }
    }

    private void showProgressDialog(String title) {
        if (mProgressDialog != null && !mProgressDialog.isShowing()) {
            mProgressDialog.setMessage(title);
            mProgressDialog.setCanceledOnTouchOutside(false);
            mProgressDialog.show();
        }
    }

    private void closeProgressDialog() {
        if (mProgressDialog != null && mProgressDialog.isShowing()) {
            mProgressDialog.dismiss();
        }
    }

    private void showToast(String title) {
        Toast.makeText(this, title, Toast.LENGTH_LONG).show();
    }

    //    login request
    private void login() {
        String name = mUserNameEditText.getText().toString().trim();
        String password = mUserPwdEditText.getText().toString().trim();
        if (name.length() == 0 || password.length() == 0) {
            showToast("please input name and password");
            return;
        }
        this.loginStatus = true;
        showProgressDialog("Login...");
        CommonOkHttpClient okHttpInstance = CommonOkHttpClient.getInstance(this);
        Map<String, String> params = new HashMap<>();
        params.put("email", name);
        params.put("password", password);
        okHttpInstance.doPost(Constants.ROOT + Constants.LOGIN, null, params);
    }

    //    intent to task activity
    private void showTaskListActivity() {
        Intent intent = new Intent();
        intent.setClass(this, FlashDriverPackageListActivity.class);
        this.startActivity(intent);
        this.finish();
    }

    //  send google token to server
    private void sendRegistrationToServer() {
        if (mFlashSharedPreferences != null) {
            String googleToken = mFlashSharedPreferences.getString("googleToken", "");
            if (!TextUtils.isEmpty(googleToken)) {
                String uuid = mFlashSharedPreferences.getString("uuid", "");
                String deviceId = Settings.System.getString(getContentResolver(), Settings.System.ANDROID_ID);
                Map<String, String> params = new HashMap<>();
                Util.debugApp('d', "send google token param uuid " + uuid);
                Util.debugApp('d', "send google token param deviceId " + deviceId);
                params.put("device_token", googleToken);
                params.put("device_id", deviceId);
                params.put("uuid", uuid);
                CommonOkHttpClient okHttpInstance = CommonOkHttpClient.getInstance(this);
                okHttpInstance.doPost(Constants.ROOT + Constants.REGISTER_DEVICE_TOKEN, null, params);
            } else {
                Util.debugApp('d', "google token is empty ");
                showTaskListActivity();
            }
        }
    }

    private void saveUserInfo(Bundle bundle) {
        String name = mUserNameEditText.getText().toString();
        String loginResponse = bundle.get("login").toString();
        String token = Util.getJsonKeyValue("token", loginResponse);
        String uuid = Util.getJsonKeyValue("uuid", loginResponse);
        SharedPreferences.Editor editor = mFlashSharedPreferences.edit();
        if (mSaveUserInfo) {
            editor.putString("userName", name);
        }
        editor.putString("token", token);
        editor.putString("uuid", uuid);
        if (Util.DEBUG) {
            String googleToken = "20210723-22:00";
            editor.putString("googleToken", googleToken);
        }
        editor.commit();
        Util.debugApp('d', "save user name " + name);
        Util.debugApp('d', "save token " + token);
        Util.debugApp('d', "save uuid " + uuid);
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        Util.debugApp('d', "checkbox changed" + isChecked);
        mSaveUserInfo = isChecked;
    }

    private static class FlashDriverHandler extends Handler {

        private final WeakReference<FlashDriverLoginActivity> mActivity;

        private FlashDriverHandler(FlashDriverLoginActivity ac) {
            this.mActivity = new WeakReference<FlashDriverLoginActivity>(ac);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            FlashDriverLoginActivity activity = mActivity.get();
            if (activity != null && !activity.isFinishing()) {
                activity.closeProgressDialog();
                switch (msg.what) {
                    case Constants.LOGIN_SUCCESS_MESSAGE:
                        Util.debugApp('d', "handle received login success message");
                        Bundle bundle = msg.getData();
                        activity.saveUserInfo(bundle);
                        activity.loginStatus = false;
                        activity.sendRegistrationToServer();
                        break;
                    case Constants.LOGIN_FAILS_MESSAGE:
                        Util.debugApp('d', "handle received login fail message");
                        activity.showToast("Check Email and Password");
                        break;
                    case Constants.LOGIN_SUCCESS_FORMAT_ERROR:
                        Util.debugApp('d', "handle received login success message bug parse json error");
                        activity.showToast("Check Email and Password");
                        break;
                    case Constants.UN_KNOW_RESPONSE_CODE:
                        Bundle bundleUnKnowCode = msg.getData();
                        if (bundleUnKnowCode != null) {
                            String unKnowBody = bundleUnKnowCode.getString("codeInvalid");
                            String description = Util.getJsonKeyValue("description", unKnowBody);
                            if (description == null) {
                                activity.showToast("Network Error");
                            } else {
                                activity.showToast(description);
                            }
                        }
                        break;
                    case Constants.GOOGLE_TOKEN_SEND_SUCCESS:
                    case Constants.GOOGLE_TOKEN_SEND_FAIL:
                        activity.showTaskListActivity();
                        break;
                }
            }
        }
    }

    @Override
    public void onClick(View v) {
        boolean connect = Util.isNetworkAvailable(this);
        if (!connect) {
            showToast("Please check your network state");
            return;
        }
        int id = v.getId();
        switch (id) {
            case R.id.user_name_clear:
                Util.debugApp('d', "clear user name");
                mUserNameEditText.setText("");
                break;
            case R.id.user_pwd_clear:
                Util.debugApp('d', "clear password");
                mUserPwdEditText.setText("");
                break;
            case R.id.user_pwd_show:
                Util.debugApp('d', "show password");
                Drawable drawableOpen = ResourcesCompat.getDrawable(getResources(), R.drawable.eye_open, null);
                Drawable drawableClose = ResourcesCompat.getDrawable(getResources(), R.drawable.eye_close, null);
                boolean showPassword = (boolean) mShowUserPwdImageView.getTag(R.id.password_show);
                if (showPassword) {
                    mShowUserPwdImageView.setBackground(drawableClose);
                    mShowUserPwdImageView.setTag(R.id.password_show, false);
                    mUserPwdEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
                } else {
                    mShowUserPwdImageView.setBackground(drawableOpen);
                    mShowUserPwdImageView.setTag(R.id.password_show, true);
                    mUserPwdEditText.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
                }
                break;
            case R.id.login_button:
                Util.debugApp('d', "start login");
                login();
                break;
        }
    }

    @Override
    public void success(Response response) {
        if (mHandler != null) {
            if (this.loginStatus) {
                Message loginSuccessMessage = mHandler.obtainMessage();
                try {
                    String body = response.body().string();
                    Util.debugApp('d', "login success body " + body);
//              if token is empty then login is fail
                    String token = Util.getJsonKeyValue("token", body);
                    if (TextUtils.isEmpty(token)) {
                        loginSuccessMessage.what = Constants.LOGIN_SUCCESS_FORMAT_ERROR;
                    } else {
                        loginSuccessMessage.what = Constants.LOGIN_SUCCESS_MESSAGE;
                        Bundle bundle = new Bundle();
                        bundle.putString("login", body);
                        loginSuccessMessage.setData(bundle);
                    }
                } catch (IOException e) {
                    Util.debugApp('e', "login success but message error" + e.toString());
                    loginSuccessMessage.what = Constants.LOGIN_SUCCESS_FORMAT_ERROR;
                }
                mHandler.sendMessage(loginSuccessMessage);
            } else {
                Util.debugApp('d', "start to sending google token success");
                Message googleMessage = mHandler.obtainMessage();
                googleMessage.what = Constants.GOOGLE_TOKEN_SEND_SUCCESS;
                mHandler.sendMessage(googleMessage);
            }
        }
    }

    @Override
    public void fail(IOException exception) {
//        exception.printStackTrace();
        if (mHandler != null) {
            if (this.loginStatus) {
                Util.debugApp('d', "login fail" + exception.toString());
                Message loginFailMessage = mHandler.obtainMessage();
                if (loginFailMessage != null) {
                    loginFailMessage.what = Constants.LOGIN_FAILS_MESSAGE;
                    mHandler.sendMessage(loginFailMessage);
                }
            } else {
                Util.debugApp('d', "save token fail" + exception.toString());
                Message googleMessage = mHandler.obtainMessage();
                if (googleMessage != null) {
                    googleMessage.what = Constants.GOOGLE_TOKEN_SEND_FAIL;
                    mHandler.sendMessage(googleMessage);
                }
            }
        }
    }

    @Override
    public void codeInvalid(Response response) {
        if (mHandler != null) {
            if (this.loginStatus) {
                Util.debugApp('d', "login response code error");
                Message loginUnKnowMessage = mHandler.obtainMessage();
                try {
                    loginUnKnowMessage.what = Constants.UN_KNOW_RESPONSE_CODE;
                    String body = response.body().string();
                    Util.debugApp('d', "codeInvalid " + body);
                    Bundle bundle = new Bundle();
                    bundle.putString("codeInvalid", body);
                    loginUnKnowMessage.setData(bundle);
                    mHandler.sendMessage(loginUnKnowMessage);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                Util.debugApp('d', "save token error");
                Message googleMessage = mHandler.obtainMessage();
                if (googleMessage != null) {
                    googleMessage.what = Constants.GOOGLE_TOKEN_SEND_FAIL;
                    mHandler.sendMessage(googleMessage);
                }
            }
        }
    }
}
